package com.gxa.service.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.common.base.RespResult;
import com.gxa.common.utils.FileUtils;
import com.gxa.service.dto.ServiceDetailsDto;
import com.gxa.service.entity.*;


import com.gxa.service.mapper.*;

import com.gxa.service.openfeigin.SettingOpenFeign;
import com.gxa.service.service.ServicesService;
import com.gxa.service.vo.*;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 *
 */
@Service
public class ServicesServiceImpl extends ServiceImpl<ServicesMapper, Services>
    implements ServicesService {
    @Autowired
    private ServicesMapper servicesMapper;
    @Autowired
    private ServiceSlabelMapper serviceSlabelMapper;
    @Autowired
    private SpecificationAreaMapper specificationAreaMapper;
    @Autowired
    private SpecificationMapper specificationMapper;
    @Autowired
    private ServiceInfoMapper serviceInfoMapper;
    @Autowired
    private ServiceDetailsMapper serviceDetailsMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SettingOpenFeign settingOpenFeign;

//    单机模式下lock锁
    private Lock lock=new ReentrantLock();

    @Autowired
    private Redisson redisson;

    public static final String REDIS_LOCK = "redis_lock";
    @Autowired
    private ServiceInfoMapper serviceInfosMapper;
    @Override
    public RespResult updateIsRecommend(Integer id,Integer isRecommend) {
        try {
//            上锁
            lock.lock();
            int row = servicesMapper.updateIsRecommend(id, isRecommend);
        } finally {
//            释放锁
            lock.unlock();
        }
        return RespResult.success();
    }

    @Override
    public RespResult updateState(Integer id,Integer state) {
//        Map resultMap = new HashMap();
//        RLock redissonLock = redisson.getLock(REDIS_LOCK);
//        redissonLock.lock();
//        try {
//            Object result = redisTemplate.opsForValue().get("updateState");
//            int stateRedis = Integer.parseInt(result.toString());
//            if(stateRedis == 0) {
                int row = servicesMapper.updateState(id, state);
                return RespResult.success();
//            }
//        }finally {
//            if(redissonLock.isLocked() && redissonLock.isHeldByCurrentThread()) {
//                redissonLock.unlock();
//            }
//        }
//        return RespResult.success("稍后再试");
    }

    /**
     * redis存储
     * @param value
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public RespResult findService(Integer value, Integer currentPage, Integer pageSize) {

        String rides="findService"+currentPage+pageSize;
        //获取到redisTemplate对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //序列化redisTemplate模板
        redisTemplate.setHashKeySerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());

        Page<allServiceVo> list= (Page<allServiceVo>) valueOperations.get(rides);
        if(list==null) {
            Page<allServiceVo> page = new Page<>(currentPage, pageSize);
            list = servicesMapper.findService(value, page);
            System.out.println(list.getRecords());
            valueOperations.set(rides,list,5, TimeUnit.MINUTES);
        }
        return RespResult.success(list);
    }

    @Override
//  @Cacheable(value = "list", key = "#dataF")
    public RespResult findServiceByTime(String dataF, String dataL, Integer currentPage, Integer pageSize) {
        Page<allServiceVo> page=new Page<>(currentPage,pageSize);
        Page<allServiceVo> list=servicesMapper.findServiceByTime(dataF,dataL,page);
        return RespResult.success(list);
    }

    @Override
    public RespResult findServiceType() {
//        List<ServiceTypeVo> list=servicesMapper.findServiceType();

        return settingOpenFeign.findServiceType();
    }

    @Override
    public RespResult findSetService(Integer id) {
//        List<ServiceTypeVo> list=servicesMapper.findSetService(id);
        return settingOpenFeign.findSetService(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RespResult findServiceById(Integer id) {
        ServiceVo serviceVo=new ServiceVo();
//        基础信息
        Services services=servicesMapper.findServiceById(id);
        serviceVo.setServices(services);
//        服务标签
        List<ServiceLabelVo> labels=serviceSlabelMapper.findLabelsById(services.getId());
        serviceVo.setLabelIds(labels);
//        定价信息
        List<SpecificationAreaVo> specificationAreaVo=specificationMapper.findSpecificationBySetId(services.getServiceNameId());
        serviceVo.setSpecificationAreaVos(specificationAreaVo);
//        服务资料
        List<ServiceInfo> infos=serviceInfoMapper.findAllByServiceId(services.getId());
        serviceVo.setInfos(infos);
//        服务详情
        ServiceDetails serviceDetails=serviceDetailsMapper.findAllByServiceId(services.getId());
        serviceVo.setServiceDetails(serviceDetails);
        return RespResult.success(serviceVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RespResult addService(ServiceDetailsDto serviceDetailsDto) {
//        插入服务信息
        Services services=serviceDetailsDto.getServices();
        services.setMakeTime(new Date());
//        获取服务标签连接的服务id
        servicesMapper.addService(services);
        Integer id=services.getId();
//        System.out.println(services.getId());
//        服务标签
        List<Integer> ids=serviceDetailsDto.getIds();
        for(int i=0;i<ids.size();i++){
             serviceSlabelMapper.addLable(ids.get(i), id);
        }
//        serviceSlabelMapper.addLable(ids,id);
//      服务资料
        List<ServiceInfo> serviceInfos=serviceDetailsDto.getInfos();
        for(int i=0;i<serviceInfos.size();i++){
            ServiceInfo serviceInfo=serviceInfos.get(i);
            serviceInfo.setServiceId(id);
            serviceInfosMapper.insert(serviceInfo);
        }
//        获取资料id为添加图片做准备
        List<Integer> idImgs =serviceInfosMapper.findIds(id);

//       服务详情
        ServiceDetails serviceDetails=serviceDetailsDto.getServiceDetails();
        serviceDetails.setServiceId(id);
        serviceDetailsMapper.insert(serviceDetails);

        return RespResult.success(idImgs);
//        return RespResult.success(services.getId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public RespResult updateService(ServiceDetailsDto serviceDetailsDto) {
        Services services=serviceDetailsDto.getServices();
        servicesMapper.updateById(services);
//      服务标签
        QueryWrapper<ServiceSlabel> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("service_id",services.getId());
        serviceSlabelMapper.delete(queryWrapper);
        List<Integer> ids=serviceDetailsDto.getIds();
            for(int i=0;i<ids.size();i++){
            serviceSlabelMapper.addLable(ids.get(i), services.getId());
        }
        //      服务资料
        List<ServiceInfo> serviceInfos=serviceDetailsDto.getInfos();
        serviceInfoMapper.deleteByServiceId(services.getId());
        for(int i=0;i<serviceInfos.size();i++){
            ServiceInfo serviceInfo=serviceInfos.get(i);
            serviceInfosMapper.insert(serviceInfo);
        }
        //       服务详情
        ServiceDetails serviceDetails=serviceDetailsDto.getServiceDetails();
        serviceDetailsMapper.updateById(serviceDetails);
        return RespResult.success(services.getId());
    }

    @Override
    public RespResult addServiceImg(MultipartFile file, Integer id, Integer order,HttpServletRequest request) {
        try{

            ServiceInfo serviceInfo1=serviceInfoMapper.selectById(id);
            String imgUrl = FileUtils.saveImage(file, request, FileUtils.SERVICE);

            ServiceInfo serviceInfo=new ServiceInfo();
            serviceInfo.setId(id);
            if (order == 1) {
                if(serviceInfo1.getImgOne()!=null) {
                    FileUtils.deleteFile(serviceInfo1.getImgOne());
                }
                serviceInfo.setImgOne(imgUrl);
            }else {
                if(serviceInfo1.getImgTwo()!=null) {
                    FileUtils.deleteFile(serviceInfo1.getImgTwo());
                }
                serviceInfo.setImgTwo(imgUrl);
            }
            serviceInfoMapper.updateById(serviceInfo);
            return RespResult.success("添加图片成功");
        }catch (Exception e){
            e.printStackTrace();
            return RespResult.error("添加失败");
        }
    }

    @Override
    public RespResult findService1(Integer currentPage, Integer pageSize) {

        String key="findService1";
        Long size = null;
        //序列化redisTemplate模板
//        redisTemplate.setHashKeySerializer(new JdkSerializationRedisSerializer());
//        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        List<allServiceVo> list=redisTemplate.opsForList().range(key,currentPage * pageSize, (currentPage+1)*pageSize-1);
        if(list.size()==0) {
            list = servicesMapper.findService1();
            System.out.println(list);
            for (int i = 0; i < list.size(); i++) {
                redisTemplate.opsForList().rightPush(key, JSON.toJSONString(list.get(i)));
            }
            list=redisTemplate.opsForList().range(key,currentPage * pageSize, (currentPage+1)*pageSize-1);
            System.out.println(list);
            size=redisTemplate.opsForList().size(key);
        }
        Map map=new HashMap();
        map.put("service",list);
        map.put("total",size);
        return RespResult.success(map);
    }

}




